module counter #(parameter DATA_WIDTH = 8, INT_SIZE = 8) (
	input clk,
	input reset_n,
	input [DATA_WIDTH - 1 : 0] data,
	output [INT_SIZE - 1 : 0] alpha,
	output valid
);

reg [INT_SIZE - 1 : 0] cycles;
reg [2*DATA_WIDTH - 1 : 0] changes;
reg [DATA_WIDTH - 1 : 0] data_old;
wire [DATA_WIDTH - 1 : 0] differential;

genvar i;
wire [INT_SIZE - 1 : 0] summation_steps [DATA_WIDTH - 2 : 0];
generate
	assign summation_steps[0] = differential[0] + differential[1];
	for (i = 0; i < DATA_WIDTH - 2; i = i + 1) begin
		assign summation_steps[i + 1] = summation_steps[i] + differential[i + 2];
	end
endgenerate

// once valid goes high, we know 2**INT_SIZE cycles have passed, so normalization is trivial
assign valid = cycles == (2**INT_SIZE - 1);
// alpha is simply the number of changes normalized by 2**INT_SIZE (shift right)
assign alpha = changes;

assign differential = data ^ data_old;

always @(posedge clk) begin
	if (reset_n == 1'b0) begin
		cycles <= 0;
		changes <= 0;
		data_old <= 0;
	end else begin
		cycles <= cycles + 1;
		changes <= changes;
		if (cycles == (2**INT_SIZE - 1)) begin
			cycles <= 0;
			changes <= 0;
		end else begin
			changes <= changes + summation_steps[DATA_WIDTH - 2];
		end
		data_old <= data;
	end
end

endmodule